function c = uunion(a, b, varargin)
% uunion  - unsorted set union.
%
% FORMAT:       u = uunion(a, b [, varargin])
%
% Input fields:
%
%       a, b        input vectors of same class type
%
% Output fields:
%
%       u           output union (unsorted)
%
% Note: In contrast to union that always sorts the results,
%       uunion(A,B) will keep the original order of A and add
%       any additional values of B in the order they occur in B.
%       Otherwise, the same syntax additions apply as with UNION.
%
% See also union

% Version:  v0.5c
% Build:    6120415
% Date:     Dec-04 2006, 3:15 PM CET
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin < 2 || ...
   ~strcmp(class(a), class(b))
    error( ...
        'BVQXtools:BadArgument', ...
        'Two arguments of the same class must be given for uunion.' ...
    );
end

% prepare vars
rows = false;
cac  = 0;

% check third arg
if nargin > 2
    if ischar(varargin{end}) && ...
        strcmpi(varargin{end}(:)', 'rows')
        rows = true;
        carg = nargin - 3;
    else
        rows = false;
        carg = nargin - 2;
    end
    if carg > 0
        for cac = 1:carg
            if ~strcmp(class(a), class(varargin{cac}))
                cac = cac - 1;
                break;
            end
        end
    end
end

% what dim to use for concat
if ~rows
    mdim = length(size(a));
    cdim = find(size(a) > 1);
    if isempty(cdim)
        cdim = find(size(b) > 1);
    end
    if isempty(cdim)
        cdim = 1;
    else
        cdim = cdim(1);
    end
    rdim = [ones(1,cdim-1) 0 ones(1,mdim-cdim)];
end

% try first union call
try
    if ~rows
        a = a(:);
        b = b(:);
        [c, ib, ia] = union(b, a);
    else
        [c, ib, ia] = union(b, a, 'rows');
    end
catch
    rethrow(lasterror);
end

% resort array
if ~rows
    c = [a(sort(ia)) ; b(sort(ib))];
    try
        rdim(cdim) = numel(c);
        c = reshape(c, rdim);
    catch
        % nothing yet
    end
else
    if ischar(a)
        c = char([cellstr(a(sort(ia),:)) ; cellstr(b(sort(ib),:))]);
    else
        try
            c = [a(sort(ia),:) ; b(sort(ib),:)];
        catch
            rethrow(lasterror);
        end
    end
end

% add more arrays ?
if cac > 0
    if rows
        rows = {'rows'};
    else
        rows = {};
    end
    for cacc = 1:cac
        try
            c = uunion(c, varargin{cacc}, rows{:});
        catch
            warning( ...
                'BVQXtools:BadArgument', ...
                'Additional argument to uunion couldn''t be added.' ...
            );
        end
    end
end
